package com.songlanyun.modules.pointtobalace.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.songlanyun.common.enums.BillConstant;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.utils.DateUtils;
import com.songlanyun.common.utils.PageUtils;
import com.songlanyun.common.utils.Query;
import com.songlanyun.common.utils.custom.MathUtils;
import com.songlanyun.modules.account.entity.AccountEntity;
import com.songlanyun.modules.account.entity.UserIdentityAssetEntity;
import com.songlanyun.modules.account.entity.UserVerifiedEntity;
import com.songlanyun.modules.account.model.vo.AccountVO;
import com.songlanyun.modules.account.service.AccountService;
import com.songlanyun.modules.account.service.CommonService;
import com.songlanyun.modules.account.service.UserIdentityAssetService;
import com.songlanyun.modules.account.service.UserVerifiedService;
import com.songlanyun.modules.chain.model.dto.UserWithdrawalDTO;
import com.songlanyun.modules.memberbill.entity.SaleRefillCardBillEntity;
import com.songlanyun.modules.memberbill.service.SaleRefillCardBillService;
import com.songlanyun.modules.memberbill.service.SaleRefillVoucherBillService;
import com.songlanyun.modules.order.dao.OrderDao;
import com.songlanyun.modules.order.entity.Order;
import com.songlanyun.modules.pointconfig.entity.PointConfig;
import com.songlanyun.modules.pointconfig.service.PointConfigService;
import com.songlanyun.modules.pointtobalace.dao.BalanceToPointRecordCNHDDao;
import com.songlanyun.modules.pointtobalace.dao.BalanceToPointRecordDao;
import com.songlanyun.modules.pointtobalace.entity.BalanceToPointRecordCNHD;
import com.songlanyun.modules.pointtobalace.model.vo.BalanceToPointRecordCNHDVO;
import com.songlanyun.modules.pointtobalace.model.vo.BalanceToPointRecordCNHDVO2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.songlanyun.modules.pointtobalace.service.IBalanceToPointRecordCNHDService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 积分兑换成余额(消费额余额)Service业务层处理
 *
 * @author SH
 * @date 2024-03-05
 */
@Service
public class BalanceToPointRecordCNHDServiceImpl extends ServiceImpl<BalanceToPointRecordCNHDDao, BalanceToPointRecordCNHD>  implements IBalanceToPointRecordCNHDService {

    @Autowired
    private BalanceToPointRecordCNHDDao balanceToPointRecordCNHDDao;

    @Autowired
    private AccountService accountService;

    @Autowired
    private UserVerifiedService userVerifiedService;

    @Autowired
    private UserIdentityAssetService userIdentityAssetService;

    @Autowired
    private SaleRefillCardBillService saleRefillCardBillService;

    @Autowired
    private SaleRefillVoucherBillService saleRefillVoucherBillService;

    @Autowired
    private CommonService commonService;

    @Autowired
    private PointConfigService pointConfigService;



    /**
     * 查询积分兑换成余额(消费额余额)
     *
     * @param id 积分兑换成余额(消费额余额)主键
     * @return 积分兑换成余额(消费额余额)
     */
    @Override
    public BalanceToPointRecordCNHD selectBalanceToPointRecordCNHDById(Long id)
    {
        return balanceToPointRecordCNHDDao.selectBalanceToPointRecordCNHDById(id);
    }

    /**
     * 查询积分兑换成余额(消费额余额)列表
     *
     * @param balanceToPointRecordCNHD 积分兑换成余额(消费额余额)
     * @return 积分兑换成余额(消费额余额)
     */
    @Override
    public List<BalanceToPointRecordCNHD> selectBalanceToPointRecordCNHDList(BalanceToPointRecordCNHD balanceToPointRecordCNHD)
    {
        return balanceToPointRecordCNHDDao.selectBalanceToPointRecordCNHDList(balanceToPointRecordCNHD);
    }

    /**
     * 新增积分兑换成余额(消费额余额)
     *
     * @param balanceToPointRecordCNHD 积分兑换成余额(消费额余额)
     * @return 结果
     */
    @Override
    public int insertBalanceToPointRecordCNHD(BalanceToPointRecordCNHD balanceToPointRecordCNHD)
    {
        balanceToPointRecordCNHD.setCreateTime(new Date());
        return balanceToPointRecordCNHDDao.insertBalanceToPointRecordCNHD(balanceToPointRecordCNHD);
    }

    /**
     * 修改积分兑换成余额(消费额余额)
     *
     * @param balanceToPointRecordCNHD 积分兑换成余额(消费额余额)
     * @return 结果
     */
    @Transactional
    @Override
    public int updateBalanceToPointRecordCNHD(BalanceToPointRecordCNHD balanceToPointRecordCNHD)
    {

        int i = balanceToPointRecordCNHDDao.updateBalanceToPointRecordCNHD(balanceToPointRecordCNHD);

        if (i > 0){
            // 修改表成功
            Integer examine = balanceToPointRecordCNHD.getExamine();
            if (examine == 1){
//                // 审核通过
//                UserIdentityAssetEntity userIdentityAssetEntity = userIdentityAssetService.getById(balanceToPointRecordCNHD.getUserId());
//                BigDecimal exchangeVoucher = userIdentityAssetEntity.getVoucher();
//                //现有兑换券余额
//                if (userIdentityAssetEntity.getVoucher() == null){
//                    exchangeVoucher = BigDecimal.ZERO;
//                }
//                //增加后的兑换券余额
//                BigDecimal addExchangeVoucher = exchangeVoucher.add(balanceToPointRecordCNHD.getHandlingFee());
//                userIdentityAssetEntity.setVoucher(addExchangeVoucher);
//                userIdentityAssetService.updateById(userIdentityAssetEntity);
                saleRefillVoucherBillService.addBalance(balanceToPointRecordCNHD.getUserId(),balanceToPointRecordCNHD.getHandlingFee(),null,BillConstant.InnerMode.CNHD_BALANCE,BillConstant.InnerMode.getMsgByCode(11));
            }else if (examine == 2) {
                //  审核不通过
                saleRefillCardBillService.addBalance(balanceToPointRecordCNHD.getUserId(),balanceToPointRecordCNHD.getGiveBalance(),null,BillConstant.InnerMode.CNHD_TO_BALANCE,BillConstant.InnerMode.getMsgByCode(10));
            }
            return i;
        }else if (i == 0) {
            return i;
        }
        return 0;
    }

    @Transactional
    @Override
    public boolean createWithdrawalBalance(UserWithdrawalDTO userWithdrawalDTO) {

        UserVerifiedEntity userVerifiedEntity = userVerifiedService.getById(userWithdrawalDTO.getUid());

        // 先做字段校验
        StringBuffer invalidFields = new StringBuffer();
        //如果没实名先去实名
        if (userVerifiedEntity == null){
            if(invalidFields.length() > 0) {
                invalidFields.append("、");
            }
            invalidFields.append("请先实名认证");
        }
        if(userWithdrawalDTO.getUid() == null){
            if(invalidFields.length() > 0) {
                invalidFields.append("、");
            }
            invalidFields.append("请输入uid");
        }
        if(userWithdrawalDTO.getUserName().isEmpty()){
            if(invalidFields.length() > 0) {
                invalidFields.append("、");
            }
            invalidFields.append("请输入姓名");
        }
        if(userWithdrawalDTO.getUserPhone().isEmpty()){
            if(invalidFields.length() > 0) {
                invalidFields.append("、");
            }
            invalidFields.append("请输入用户手机号");
        }
        if(userWithdrawalDTO.getIdNo().isEmpty()){
            if(invalidFields.length() > 0) {
                invalidFields.append("、");
            }
            invalidFields.append("银行卡号不能为空");
        }
        if(userWithdrawalDTO.getBankPhone().isEmpty()){
            if(invalidFields.length() > 0) {
                invalidFields.append("、");
            }
            invalidFields.append("银行预留手机号不能为空");
        }
        if(userWithdrawalDTO.getIdentityCard().isEmpty()){
            if(invalidFields.length() > 0) {
                invalidFields.append("、");
            }
            invalidFields.append("身份证号不能为空");
        }
        if(invalidFields.length() > 0) {
            throw new RRException(invalidFields.toString());
        }
        if(userWithdrawalDTO.getAmount().compareTo(new BigDecimal(100)) < 0){
            throw new RRException("提现金额不能小于100元");
        }

        // 再做业务处理
        AccountEntity user = accountService.getById(userWithdrawalDTO.getUid());
//        //验证码校验
//        commonService.checkVerCode(user.getMobile(), userWithdrawalDTO.getVerfityCode());

        //获取用户提现配置
        PointConfig pointConfig = pointConfigService.loadConfig(true);

        //cnhd提现手续费比率
        BigDecimal withdrawHandlingFeeCnhd = pointConfig.getWithdrawHandlingFeeCnhd();

        //cnhd提现的手续费（也就是兑换券的值）
        //BigDecimal handlingFeeCnhd = MathUtils.setScaleDown(userWithdrawalDTO.getAmount().doubleValue() * withdrawHandlingFeeCnhd.doubleValue() / 100, 8);
        BigDecimal handlingFeeCnhd = userWithdrawalDTO.getAmount().multiply(BigDecimal.valueOf(withdrawHandlingFeeCnhd.doubleValue()).divide(new BigDecimal(100)));

        //真实的到账的cnhd的值
        //BigDecimal facePointCnhd = MathUtils.setScaleDown(userWithdrawalDTO.getAmount().doubleValue() - handlingFeeCnhd.doubleValue(), 8);
        BigDecimal facePointCnhd = userWithdrawalDTO.getAmount().subtract(BigDecimal.valueOf(handlingFeeCnhd.doubleValue()));

//        // 审核通过
//        UserIdentityAssetEntity userIdentityAssetEntity = userIdentityAssetService.getById(user.getId());
//        BigDecimal exchangeVoucher = userIdentityAssetEntity.getVoucher();
//        //现有兑换券余额
//        if (userIdentityAssetEntity.getVoucher() == null){
//            exchangeVoucher = BigDecimal.ZERO;
//        }
//        //增加后的兑换券余额
//        BigDecimal addExchangeVoucher = exchangeVoucher.add(handlingFeeCnhd);
//        userIdentityAssetEntity.setVoucher(addExchangeVoucher);
//        userIdentityAssetService.updateById(userIdentityAssetEntity);


        BalanceToPointRecordCNHD balanceToPointRecordCNHD = new BalanceToPointRecordCNHD();
        balanceToPointRecordCNHD.setUserId(user.getId());
        balanceToPointRecordCNHD.setRealName(userWithdrawalDTO.getUserName());
        balanceToPointRecordCNHD.setMobile(userWithdrawalDTO.getUserPhone());
        balanceToPointRecordCNHD.setGiveBalance(userWithdrawalDTO.getAmount());
        balanceToPointRecordCNHD.setPointPrice(new BigDecimal("0.94"));
        //手续费
        balanceToPointRecordCNHD.setHandlingFee(handlingFeeCnhd);
        balanceToPointRecordCNHD.setFaceBalance(userWithdrawalDTO.getAmount());
        balanceToPointRecordCNHD.setFaceAddPoint(facePointCnhd);
        balanceToPointRecordCNHD.setCreateTime(new Date());
        balanceToPointRecordCNHD.setIdentityCard(userWithdrawalDTO.getIdentityCard());
        balanceToPointRecordCNHD.setBankPhone(userWithdrawalDTO.getBankPhone());
        //未审核状态
        balanceToPointRecordCNHD.setExamine(0);
        balanceToPointRecordCNHD.setBankCard(userWithdrawalDTO.getIdNo());
        //添加到数据库
        balanceToPointRecordCNHDDao.insertBalanceToPointRecordCNHD(balanceToPointRecordCNHD);

        saleRefillCardBillService.subBalance(userWithdrawalDTO.getUid(),userWithdrawalDTO.getAmount(),null,BillConstant.OuterMode.EXCHANGE_FOR_CNHD,BillConstant.OuterMode.getMsgByCode(5));

        return true;
    }

    @Override
    public PageUtils allExaminePage(Map<String, String> params) throws ParseException {
        String page = params.get("page");
        String limit = params.get("limit");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        LambdaQueryWrapper<BalanceToPointRecordCNHD> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if(StringUtils.isNotBlank(params.get("real_name"))){
            lambdaQueryWrapper.like(BalanceToPointRecordCNHD::getRealName,"%" + params.get("real_name") + "%");
        }
        if(StringUtils.isNotBlank(params.get("mobile"))){
            lambdaQueryWrapper.eq(BalanceToPointRecordCNHD::getMobile,params.get("mobile"));
        }
        String examineText = String.valueOf(params.get("examine"));
        if(StringUtils.isNotBlank(examineText) && !StringUtils.equalsIgnoreCase("null", examineText)){
            Integer examineValue = null;
            try {
                examineValue = Integer.valueOf(examineText);
            } catch (NumberFormatException e) {
                //
            }
            lambdaQueryWrapper.eq(examineValue != null && examineValue > -1, BalanceToPointRecordCNHD::getExamine,examineValue);
        }
        if(StringUtils.isNotBlank(params.get("start_time"))){
            lambdaQueryWrapper.ge(BalanceToPointRecordCNHD::getCreateTime, sdf.parse(params.get("start_time")));
        }
        if(StringUtils.isNotBlank(params.get("end_time"))){
            lambdaQueryWrapper.le(BalanceToPointRecordCNHD::getCreateTime, DateUtil.offsetSecond(DateUtil.offsetDay(sdf.parse(params.get("end_time")), 1), -1));
        }
        if("real_name".equals(params.get("sort_field"))){
            lambdaQueryWrapper.orderBy(true, StringUtils.equalsIgnoreCase("ASC", params.get("sort_type")), BalanceToPointRecordCNHD::getRealName);
        }
        if("create_time".equals(params.get("sort_field"))){
            lambdaQueryWrapper.orderBy(true, StringUtils.equalsIgnoreCase("ASC", params.get("sort_type")), BalanceToPointRecordCNHD::getCreateTime);
        }
        lambdaQueryWrapper.orderByDesc(BalanceToPointRecordCNHD::getCreateTime);
        lambdaQueryWrapper.last("LIMIT " + (Integer.parseInt(page) - 1 ) * Integer.parseInt(limit) + ", " + limit);
        List<BalanceToPointRecordCNHD> balanceToPointRecordCNHDList = this.baseMapper.selectList(lambdaQueryWrapper);

        LambdaQueryWrapper<BalanceToPointRecordCNHD> lambdaQueryWrapper2 = new LambdaQueryWrapper<>();
        if(StringUtils.isNotBlank(params.get("real_name"))){
            lambdaQueryWrapper2.like(BalanceToPointRecordCNHD::getRealName,"%" + params.get("real_name") + "%");
        }
        if(StringUtils.isNotBlank(params.get("mobile"))){
            lambdaQueryWrapper2.eq(BalanceToPointRecordCNHD::getMobile,params.get("mobile"));
        }
        if(StringUtils.isNotBlank(examineText) && !StringUtils.equalsIgnoreCase("null", examineText)){
            Integer examineValue = null;
            try {
                examineValue = Integer.valueOf(examineText);
            } catch (NumberFormatException e) {
                //
            }
            lambdaQueryWrapper2.eq(examineValue != null && examineValue > -1, BalanceToPointRecordCNHD::getExamine,examineValue);
        }
        if(StringUtils.isNotBlank(params.get("start_time"))){
            lambdaQueryWrapper2.ge(BalanceToPointRecordCNHD::getCreateTime, sdf.parse(params.get("start_time")));
        }
        if(StringUtils.isNotBlank(params.get("end_time"))){
            lambdaQueryWrapper2.le(BalanceToPointRecordCNHD::getCreateTime, DateUtil.offsetSecond(DateUtil.offsetDay(sdf.parse(params.get("end_time")), 1), -1));
        }
        Integer integer = this.baseMapper.selectCount(lambdaQueryWrapper2);

        return new PageUtils(balanceToPointRecordCNHDList, integer, Integer.parseInt(limit), Integer.parseInt(page));
    }

    /**
     * 根据过滤条件导出数据列表
     *
     * @param params 过滤条件
     * @return 符合过滤条件的数据列表
     */
    @Override
    public List<BalanceToPointRecordCNHDVO> exportList(Map<String, String> params) {
        //数据 -- 平台管理员
        List<BalanceToPointRecordCNHDVO> list = this.baseMapper.exportList(params);
        return list;
    }

    /**
     * 根据过滤条件导出数据列表
     *
     * @param params 过滤条件
     * @return 符合过滤条件的数据列表
     */
    @Override
    public List<BalanceToPointRecordCNHDVO2> exportList2(Map<String, String> params) {
        //数据 -- 平台管理员
        List<BalanceToPointRecordCNHDVO2> list = this.baseMapper.exportList2(params);
        return list;
    }

//    @Override
//    public BalanceToPointRecordCNHD create(BalanceToPointRecordCNHD entity) {
//        return null;
//    }
//
//    @Override
//    public BalanceToPointRecordCNHD modify(BalanceToPointRecordCNHD entity) {
//        return null;
//    }
//
//    @Override
//    public void remove(Long id) {
//
//    }
//
//    @Override
//    public PageUtils queryPage(Map<String, Object> params) {
//        return null;
//    }
//
//    @Override
//    public boolean saveBatch(Collection<BalanceToPointRecordCNHD> entityList) {
//        return super.saveBatch(entityList);
//    }
//
//    @Override
//    public boolean saveOrUpdateBatch(Collection<BalanceToPointRecordCNHD> entityList) {
//        return super.saveOrUpdateBatch(entityList);
//    }
//
//    @Override
//    public boolean update(Wrapper<BalanceToPointRecordCNHD> updateWrapper) {
//        return super.update(updateWrapper);
//    }

//    /**
//     * 批量删除积分兑换成余额(消费额余额)
//     *
//     * @param ids 需要删除的积分兑换成余额(消费额余额)主键
//     * @return 结果
//     */
//    @Override
//    public int deleteBalanceToPointRecordCNHDByIds(Long[] ids)
//    {
//        return balanceToPointRecordCNHDDao.deleteBalanceToPointRecordCNHDByIds(ids);
//    }

//    /**
//     * 删除积分兑换成余额(消费额余额)信息
//     *
//     * @param id 积分兑换成余额(消费额余额)主键
//     * @return 结果
//     */
//    @Override
//    public int deleteBalanceToPointRecordCNHDById(Long id)
//    {
//        return balanceToPointRecordCNHDDao.deleteBalanceToPointRecordCNHDById(id);
//    }
}
